package taskhandler

import (
	"bytes"
	"compress/zlib"
	"cvevulner/common"
	"cvevulner/models"
	"encoding/xml"
	"errors"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
)

type CvrfSa struct {
	XMLName            xml.Name            `xml:"cvrfdoc,omitempty"`
	Xmlns              string              `xml:"xmlns,attr"`
	XmlnsCvrf          string              `xml:"xmlns:cvrf,attr"`
	DocumentTitle      *DocumentTitle      `xml:"DocumentTitle,omitempty"`
	DocumentType       string              `xml:"DocumentType"`
	DocumentPublisher  *DocumentPublisher  `xml:"DocumentPublisher,omitempty"`
	DocumentTracking   *DocumentTracking   `xml:"DocumentTracking,omitempty"`
	DocumentNotes      *DocumentNotes      `xml:"DocumentNotes,omitempty"`
	DocumentReferences *DocumentReferences `xml:"DocumentReferences,omitempty"`
	ProductTree        *ProductTree        `xml:"ProductTree,omitempty"`
	Vulnerability      []Vulnerability     `xml:"Vulnerability,omitempty"`
}

type DocumentTitle struct {
	XMLName       xml.Name `xml:"DocumentTitle,omitempty"`
	XmlLang       string   `xml:"xml:lang,attr"`
	DocumentTitle string   `xml:",innerxml"`
}

type DocumentPublisher struct {
	XMLName          xml.Name `xml:"DocumentPublisher,omitempty"`
	Type             string   `xml:"Type,attr"`
	ContactDetails   string   `xml:"ContactDetails"`
	IssuingAuthority string   `xml:"IssuingAuthority"`
}

type DocumentTracking struct {
	XMLName            xml.Name         `xml:"DocumentTracking,omitempty"`
	Identification     *Identification  `xml:"Identification,omitempty"`
	Status             string           `xml:"Status"`
	Version            string           `xml:"Version"`
	RevisionHistory    *RevisionHistory `xml:"RevisionHistory,omitempty"`
	InitialReleaseDate string           `xml:"InitialReleaseDate"`
	CurrentReleaseDate string           `xml:"CurrentReleaseDate"`
	Generator          *Generator       `xml:"Generator,omitempty"`
}

type Identification struct {
	XMLName xml.Name `xml:"Identification,omitempty"`
	Id      string   `xml:"ID"`
}

type RevisionHistory struct {
	XMLName  xml.Name   `xml:"RevisionHistory,omitempty"`
	Revision []Revision `xml:"Revision,omitempty"`
}

type Revision struct {
	XMLName     xml.Name `xml:"Revision,omitempty"`
	Number      string   `xml:"Number"`
	Date        string   `xml:"Date"`
	Description string   `xml:"Description"`
}

type Generator struct {
	XMLName xml.Name `xml:"Generator,omitempty"`
	Engine  string   `xml:"Engine"`
	Date    string   `xml:"Date"`
}

type DocumentNotes struct {
	XMLName xml.Name `xml:"DocumentNotes,omitempty"`
	Note    []Note   `xml:"Note,omitempty"`
}

type Note struct {
	XMLName xml.Name `xml:"Note,omitempty"`
	Title   string   `xml:"Title,attr"`
	Type    string   `xml:"Type,attr"`
	Ordinal string   `xml:"Ordinal,attr"`
	XmlLang string   `xml:"xml:lang,attr"`
	Note    string   `xml:",innerxml"`
}

type DocumentReferences struct {
	XMLName      xml.Name       `xml:"DocumentReferences,omitempty"`
	CveReference []CveReference `xml:"Reference,omitempty"`
}

type CveReference struct {
	XMLName xml.Name `xml:"Reference,omitempty"`
	Type    string   `xml:"Type,attr"`
	CveUrl  []CveUrl `xml:"URL,omitempty"`
}

type CveUrl struct {
	XMLName xml.Name `xml:"URL,omitempty"`
	Url     string   `xml:",innerxml"`
}

type ProductTree struct {
	XMLName         xml.Name          `xml:"ProductTree,omitempty"`
	Xmlns           string            `xml:"xmlns,attr"`
	OpenEulerBranch []OpenEulerBranch `xml:"Branch,omitempty"`
}

type OpenEulerBranch struct {
	XMLName         xml.Name          `xml:"Branch,omitempty"`
	Type            string            `xml:"Type,attr"`
	Name            string            `xml:"Name,attr"`
	FullProductName []FullProductName `xml:"FullProductName,omitempty"`
}

type FullProductName struct {
	XMLName         xml.Name `xml:"FullProductName,omitempty"`
	ProductId       string   `xml:"ProductID,attr"`
	Cpe             string   `xml:"CPE,attr"`
	FullProductName string   `xml:",innerxml"`
}

type Vulnerability struct {
	XMLName         xml.Name         `xml:"Vulnerability,omitempty"`
	Ordinal         string           `xml:"Ordinal,attr"`
	Xmlns           string           `xml:"xmlns,attr"`
	CveNotes        *CveNotes        `xml:"Notes,omitempty"`
	ReleaseDate     string           `xml:"ReleaseDate"`
	Cve             string           `xml:"CVE"`
	ProductStatuses *ProductStatuses `xml:"ProductStatuses,omitempty"`
	Threats         *Threats         `xml:"Threats,omitempty"`
	CvssScoreSets   *CVSSScoreSets   `xml:"CVSSScoreSets,omitempty"`
	Remediations    *Remediations    `xml:"Remediations,omitempty"`
}

type CveNotes struct {
	XMLName xml.Name `xml:"Notes,omitempty"`
	CveNote *CveNote `xml:"Note,omitempty"`
}

type CveNote struct {
	XMLName xml.Name `xml:"Note,omitempty"`
	Title   string   `xml:"Title,attr"`
	Type    string   `xml:"Type,attr"`
	Ordinal string   `xml:"Ordinal,attr"`
	XmlLnag string   `xml:"xml:lang,attr"`
	Note    string   `xml:",innerxml"`
}

type ProductStatuses struct {
	XMLName xml.Name `xml:"ProductStatuses,omitempty"`
	Status  *Status  `xml:"Status,omitempty"`
}

type Status struct {
	XMLName   xml.Name    `xml:"Status,omitempty"`
	Type      string      `xml:"Type,attr"`
	ProductId []ProductId `xml:"ProductID,omitempty"`
}

type ProductId struct {
	XMLName   xml.Name `xml:"ProductID,omitempty"`
	ProductId string   `xml:",innerxml"`
}

type Threats struct {
	XMLName xml.Name `xml:"Threats,omitempty"`
	Threat  *Threat  `xml:"Threat,omitempty"`
}

type Threat struct {
	XMLName     xml.Name `xml:"Threat,omitempty"`
	Type        string   `xml:"Type,attr"`
	Description string   `xml:"Description"`
}

type CVSSScoreSets struct {
	XMLName  xml.Name  `xml:"CVSSScoreSets,omitempty"`
	ScoreSet *ScoreSet `xml:"ScoreSet,omitempty"`
}

type ScoreSet struct {
	XMLName   xml.Name `xml:"ScoreSet,omitempty"`
	BaseScore string   `xml:"BaseScore"`
	Vector    string   `xml:"Vector"`
}

type Remediations struct {
	XMLName     xml.Name     `xml:"Remediations,omitempty"`
	Remediation *Remediation `xml:"Remediation,omitempty"`
}

type UnRemediations struct {
	XMLName     xml.Name        `xml:"Remediations,omitempty"`
	Remediation []UnRemediation `xml:"Remediation,omitempty"`
}

type Remediation struct {
	XMLName     xml.Name `xml:"Remediation,omitempty"`
	Type        string   `xml:"Type,attr"`
	Description string   `xml:"Description"`
	Date        string   `xml:"DATE"`
	Url         string   `xml:"URL"`
}

type UnRemediation struct {
	XMLName     xml.Name `xml:"Remediation,omitempty"`
	Type        string   `xml:"Type,attr"`
	Description string   `xml:"Description"`
	Date        string   `xml:"DATE"`
	ProductId   string   `xml:"ProductID"`
}

type CveInfo struct {
	CveNum            string
	Description       string
	ProductID         string
	CveLevel          string
	BaseScore         float64
	Vector            string
	Summary           string
	OpenEulerSANumUrl string
}

// Intermediate information
type SecurityNoticeCvrf struct {
	CveNum        string
	Summary       string
	Theme         string
	ReferenceLink string
	Description   string
	Introduction  string
	CveLevel      string
	BaseScore     float64
}

type PackRpmCvrf struct {
	PackName string
}

type CveCvrf struct {
	Introduction   string
	OpenEulerSANum string
	PublicDate     string
	CveLevel       string
	OwnedComponent string
	SecurityNotice map[string][]SecurityNoticeCvrf
	PackRpmx       map[string][]PackRpm
	CveInfo        CveInfo
}

type BrachCveInfo struct {
	OpenEulerSANum string
	CvrfFileName   string
	CveNumSlice    []string
	OpenEulerScore []float64
}

type ComponentInfo struct {
	OpenEulerSANum string
	OwnedComponent string
	CveNum         []string
	CveNumMap      map[string]BrachCveInfo
	OpenEulerScore []float64
	UpdateFlag     int
	CvrfFileName   string
}

type UnaffectCvrfSa struct {
	XMLName       xml.Name                `xml:"cvrfdoc,omitempty"`
	Xmlns         string                  `xml:"xmlns,attr"`
	XmlnsCvrf     string                  `xml:"xmlns:cvrf,attr"`
	Vulnerability []UnaffectVulnerability `xml:"Vulnerability,omitempty"`
}

type UnaffectVulnerability struct {
	XMLName         xml.Name         `xml:"Vulnerability,omitempty"`
	Ordinal         string           `xml:"Ordinal,attr"`
	Xmlns           string           `xml:"xmlns,attr"`
	CveNotes        *CveNotes        `xml:"Notes,omitempty"`
	Cve             string           `xml:"CVE"`
	ProductStatuses *ProductStatuses `xml:"ProductStatuses,omitempty"`
	CvssScoreSets   *CVSSScoreSets   `xml:"CVSSScoreSets,omitempty"`
	Remediations    *UnRemediations  `xml:"Remediations,omitempty"`
}

func UnaffectReadCvrfXml(filePath string, unaffectCvrfSa *UnaffectCvrfSa) error {
	if filePath == "" || len(filePath) == 0 {
		logs.Error("read err: ", filePath)
		return errors.New("file does not exist")
	}
	fisExist, ferr := PathExists(filePath)
	if !fisExist {
		logs.Error(ferr)
		return ferr
	}
	fd, err := os.Open(filePath)
	if err != nil {
		logs.Error("open file err : ", err, ",filePath: ", filePath)
		return err
	}
	defer fd.Close()
	fileContent, err := ioutil.ReadAll(fd)
	if err != nil {
		logs.Error("read file err : ", err, ", filePath: ", filePath)
		return err
	}
	err = xml.Unmarshal(fileContent, unaffectCvrfSa)
	if err != nil {
		logs.Error("unmarshal err : ", err, ", fileContent: ", fileContent)
		return err
	}
	return nil
}

func WriteUnaffectCvrfXml(filePath string, unaffectCvrfsa *UnaffectCvrfSa) {
	os.Remove(filePath)
	xmlOutPut, outPutErr := xml.MarshalIndent(unaffectCvrfsa, "", "	")
	if outPutErr == nil {
		headerBytes := []byte(xml.Header)
		xmlOutPutData := append(headerBytes, xmlOutPut...)
		ioutil.WriteFile(filePath, xmlOutPutData, os.ModeAppend)
	} else {
		logs.Error(outPutErr)
	}
}

func ReadCvrfXml(filePath string, cvrf *CvrfSa) error {
	if filePath == "" || len(filePath) == 0 {
		logs.Error("read err: ", filePath)
		return errors.New("file does not exist")
	}
	fisExist, ferr := PathExists(filePath)
	if !fisExist {
		logs.Error(ferr)
		return ferr
	}
	fd, err := os.Open(filePath)
	if err != nil {
		logs.Error("open file err : ", err, ",filePath: ", filePath)
		return err
	}
	defer fd.Close()
	fileContent, err := ioutil.ReadAll(fd)
	if err != nil {
		logs.Error("read file err : ", err, ", filePath: ", filePath)
		return err
	}
	err = xml.Unmarshal(fileContent, cvrf)
	if err != nil {
		logs.Error("unmarshal err : ", err, ", fileContent: ", fileContent)
		return err
	}
	return nil
}

func WriteCvrfXml(filePath string, cvrfsa *CvrfSa) {
	os.Remove(filePath)
	xmlOutPut, outPutErr := xml.MarshalIndent(cvrfsa, "", "	")
	if outPutErr == nil {
		headerBytes := []byte(xml.Header)
		xmlOutPutData := append(headerBytes, xmlOutPut...)
		ioutil.WriteFile(filePath, xmlOutPutData, os.ModeAppend)
	} else {
		logs.Error(outPutErr)
	}
}

func BuildUnaffectVulnerabilitySet(unaffectCvrfsa *UnaffectCvrfSa, v models.ExcelExport,
	affectBranch string, componentMap map[string]ComponentInfo) {
	vulnerability := make([]UnaffectVulnerability, 0)
	vulnerabilityx := make([]UnaffectVulnerability, 0)
	if len(unaffectCvrfsa.Vulnerability) > 0 {
		vulnerabilityx = BuildUnaffVulnerabilitySlice(unaffectCvrfsa.Vulnerability, v, affectBranch, componentMap)
	} else {
		vulnerabilityx = BuildUnaffVulnerabilitySlice(vulnerability, v, affectBranch, componentMap)
	}
	unaffectCvrfsa.Vulnerability = vulnerabilityx
}

func BuildUnaffVulnerabilitySlice(vulnerability []UnaffectVulnerability, v models.ExcelExport,
	affectBranch string, componentMap map[string]ComponentInfo) []UnaffectVulnerability {
	cpe := affectBranch
	if vulnerability != nil && len(vulnerability) > 0 {
		cveExist := false
		for i, vl := range vulnerability {
			if vl.Cve == v.CveNum && vl.Remediations != nil && len(vl.Remediations.Remediation) > 0 &&
				vl.Remediations.Remediation[0].Description == v.InfluenceComponent {
				cpeExist := false
				for _, pid := range vl.ProductStatuses.Status.ProductId {
					if pid.ProductId == cpe {
						cpeExist = true
						break
					}
				}
				if !cpeExist {
					var productId ProductId
					productId.ProductId = cpe
					vl.ProductStatuses.Status.ProductId = append(vl.ProductStatuses.Status.ProductId, productId)
					var remediation UnRemediation
					remediation.Type = "Unaffected"
					remediation.Description = v.InfluenceComponent
					remediation.Date = common.GetCurDate()
					remediation.ProductId = cpe
					vl.Remediations.Remediation = append(vl.Remediations.Remediation, remediation)
					vulnerability[i] = vl
				}
				cveExist = true
				break
			}
		}
		if !cveExist {
			vlLenth := len(vulnerability) + 1
			vulnerabilitySlice := BuildUnaffVulnerability(vlLenth, v, componentMap, cpe)
			if len(vulnerabilitySlice) > 0 {
				vulnerability = append(vulnerability, vulnerabilitySlice...)
			}
		}
	} else {
		vlLenth := 1
		vulnerabilitySlice := BuildUnaffVulnerability(vlLenth, v, componentMap, cpe)
		vulnerability = append(vulnerability, vulnerabilitySlice...)
	}
	return vulnerability
}

func BuildUnaffVulnerability(vlLenth int, v models.ExcelExport,
	componentMap map[string]ComponentInfo, cpe string) []UnaffectVulnerability {
	vulnerabilitySlice := make([]UnaffectVulnerability, 0)
	var vulnerability UnaffectVulnerability
	vulnerability.Xmlns = "http://www.icasi.org/CVRF/schema/vuln/1.1"
	vulnerability.Ordinal = strconv.Itoa(vlLenth)
	var cveNotes CveNotes
	var cveNote CveNote
	cveNote.Ordinal = strconv.Itoa(vlLenth)
	cveNote.Type = "General"
	cveNote.Title = "Vulnerability Description"
	cveBrief := XmlSpecCharHand(v.CveBrief)
	cveNote.Note = cveBrief
	cveNote.XmlLnag = "en"
	cveNotes.CveNote = &cveNote
	vulnerability.CveNotes = &cveNotes
	vulnerability.Cve = v.CveNum
	var productStatuses ProductStatuses
	var status Status
	status.Type = "Unaffected"
	var productId ProductId
	productId.ProductId = cpe
	productIdSlice := make([]ProductId, 0)
	productIdSlice = append(productIdSlice, productId)
	status.ProductId = productIdSlice
	productStatuses.Status = &status
	vulnerability.ProductStatuses = &productStatuses
	var cVSSScoreSets CVSSScoreSets
	var scoreSet ScoreSet
	scoreSet.BaseScore = fmt.Sprintf("%.1f", v.OpenEulerScore)
	scoreSet.Vector = v.OvectorVule
	cVSSScoreSets.ScoreSet = &scoreSet
	vulnerability.CvssScoreSets = &cVSSScoreSets
	var remediations UnRemediations
	remediationSlice := make([]UnRemediation, 0)
	var remediation UnRemediation
	remediation.Type = "Unaffected"
	remediation.Description = v.InfluenceComponent
	remediation.Date = common.GetCurDate()
	remediation.ProductId = cpe
	remediationSlice = append(remediationSlice, remediation)
	remediations.Remediation = remediationSlice
	vulnerability.Remediations = &remediations
	vulnerabilitySlice = append(vulnerabilitySlice, vulnerability)
	return vulnerabilitySlice
}

func BranchExist(affectBranch string, cvrfFileList map[string][]string) []string {
	brancsList, keyOk := cvrfFileList[BRANCHSKEY]
	if !keyOk {
		localBran := make([]string, 0)
		localBran = append(localBran, affectBranch)
		cvrfFileList[BRANCHSKEY] = localBran
	} else {
		brlFlag := false
		for _, brl := range brancsList {
			if brl == affectBranch {
				brlFlag = true
				break
			}
		}
		if !brlFlag {
			brancsList = append(brancsList, affectBranch)
			cvrfFileList[BRANCHSKEY] = brancsList
		}
	}
	brancsListx, _ := cvrfFileList[BRANCHSKEY]
	if len(brancsListx) > 1 {
		sort.Strings(brancsListx)
	}
	return brancsListx
}

func BuilddocumentNotes(cvrfsa *CvrfSa, v models.ExcelExport,
	introduction, topic, affectBranch string,
	componentMap map[string]ComponentInfo,
	branchList []string, branchFlag int) {
	documentNotes := cvrfsa.DocumentNotes
	if documentNotes == nil || cvrfsa.DocumentNotes.Note == nil ||
		len(cvrfsa.DocumentNotes.Note) == 0 {
		var documentNotesx DocumentNotes
		note := make([]Note, 0)
		var noteSynopsis Note
		noteSynopsis.Title = "Synopsis"
		noteSynopsis.Type = "General"
		noteSynopsis.Ordinal = "1"
		noteSynopsis.XmlLang = "en"
		noteSynopsis.Note = v.Summary
		note = append(note, noteSynopsis)
		var noteSummary Note
		noteSummary.Title = "Summary"
		noteSummary.Type = "General"
		noteSummary.Ordinal = "2"
		noteSummary.XmlLang = "en"
		noteSummary.Note = introduction
		note = append(note, noteSummary)
		var noteDescription Note
		noteDescription.Title = "Description"
		noteDescription.Type = "General"
		noteDescription.Ordinal = "3"
		noteDescription.XmlLang = "en"
		descriptionStr := strings.ReplaceAll(v.Description, "\n\n", "\r\n\r\n")
		descriptionStr = XmlSpecCharHand(descriptionStr)
		noteDescription.Note = descriptionStr
		note = append(note, noteDescription)
		var noteTopic Note
		noteTopic.Title = "Topic"
		noteTopic.Type = "General"
		noteTopic.Ordinal = "4"
		noteTopic.XmlLang = "en"
		topic := strings.ReplaceAll(topic, "\n\n", "\r\n\r\n")
		topic = XmlSpecCharHand(topic)
		noteTopic.Note = topic
		note = append(note, noteTopic)
		var noteSeverity Note
		noteSeverity.Title = "Severity"
		noteSeverity.Type = "General"
		noteSeverity.Ordinal = "5"
		noteSeverity.XmlLang = "en"
		cveLevel := models.OpenEulerScoreProc(v.OpenEulerScore)
		noteSeverity.Note = cveLevel
		note = append(note, noteSeverity)
		var noteComponent Note
		noteComponent.Title = "Affected Component"
		noteComponent.Type = "General"
		noteComponent.Ordinal = "6"
		noteComponent.XmlLang = "en"
		noteComponent.Note = v.InfluenceComponent
		note = append(note, noteComponent)
		documentNotesx.Note = note
		cvrfsa.DocumentNotes = &documentNotesx
	} else {
		branchCount := len(branchList)
		note := cvrfsa.DocumentNotes.Note
		ownedComponent := ""
		if len(v.InfluenceComponent) > 1 {
			ownedComponent = v.InfluenceComponent
		} else {
			ownedComponent = v.OwnedComponent
		}
		componentInfo := componentMap[ownedComponent]
		notex := make([]Note, 0)
		for _, te := range note {
			if te.Title == "Description" {
				descriptionStr := strings.ReplaceAll(v.Description, "\n\n", "\r\n\r\n")
				descriptionStr = XmlSpecCharHand(descriptionStr)
				dSplit := strings.Split(descriptionStr, "Security Fix(es):")
				if len(dSplit) > 1 {
					if !strings.Contains(te.Note, dSplit[0]) {
						te.Note = dSplit[0] + te.Note
					}
					if !strings.Contains(te.Note, dSplit[1]) {
						te.Note += dSplit[1]
					}
				}
				te.Note = te.Note
			}
			if te.Title == "Topic" {
				vcn := ""
				if branchFlag == 1 {
					vcn = strings.Join(componentInfo.CveNum, ";\n")
					theme, err := models.GetCanExportTheme(vcn, v.InfluenceComponent, affectBranch)
					if err == nil && len(theme) > 1 {
						theme = strings.ReplaceAll(theme, "\n\n", "\r\n\r\n")
						theme = XmlSpecCharHand(theme)
						if branchCount <= 1 {
							te.Note = theme
						} else if branchCount == 2 {
							te.Note = strings.ReplaceAll(theme, affectBranch, strings.Join(branchList, " and "))
						} else {
							reBanch := strings.Join(branchList[:len(branchList)-1], ",") + " and " + branchList[len(branchList)-1]
							te.Note = strings.ReplaceAll(theme, affectBranch, reBanch)
						}
					}
				} else {
					vcn = strings.Join(componentInfo.CveNumMap[affectBranch].CveNumSlice, ";\n")
					theme, err := models.GetCanExportTheme(vcn, v.InfluenceComponent, affectBranch)
					if err == nil && len(theme) > 1 {
						theme = strings.ReplaceAll(theme, "\n\n", "\r\n\r\n")
						theme = XmlSpecCharHand(theme)
						te.Note = theme
					}
				}
			}
			if te.Title == "Summary" {
				if branchFlag == 1 {
					if branchCount <= 1 {
						te.Note = v.Introduction
					} else if branchCount == 2 {
						te.Note = strings.ReplaceAll(v.Introduction, affectBranch, strings.Join(branchList, " and "))
					} else {
						reBanch := strings.Join(branchList[:len(branchList)-1], ",") + " and " + branchList[len(branchList)-1]
						te.Note = strings.ReplaceAll(v.Introduction, affectBranch, reBanch)
					}
				} else {
					te.Note = v.Introduction
				}

			}
			if te.Title == "Severity" {
				var openEulerScoreSlice []float64
				if branchFlag == 1 {
					openEulerScoreSlice = componentInfo.OpenEulerScore
				} else {
					openEulerScoreSlice = componentInfo.CveNumMap[affectBranch].OpenEulerScore
				}

				if len(openEulerScoreSlice) > 1 {
					sort.Float64s(openEulerScoreSlice)
				}
				if len(openEulerScoreSlice) > 0 {
					cveLevel := models.OpenEulerScoreProc(openEulerScoreSlice[len(openEulerScoreSlice)-1])
					te.Note = cveLevel
				}
			}
			notex = append(notex, te)
		}
		cvrfsa.DocumentNotes.Note = notex
	}
}

func BuildDocumentTitle(cvrfsa *CvrfSa, v models.ExcelExport, affectBranch string,
	cvrfFileList map[string][]string, componentMap map[string]ComponentInfo,
	curDate string, branchList []string, branchFlag int) {
	var documt DocumentTitle
	introduction := ""
	topic := ""
	branchCount := len(branchList)
	ownedComponent := ""
	if len(v.InfluenceComponent) > 1 {
		ownedComponent = v.InfluenceComponent
	} else {
		ownedComponent = v.OwnedComponent
	}
	componentInfo := componentMap[ownedComponent]
	localOpenEulerSANum := ""
	if branchFlag == 1 {
		localOpenEulerSANum = componentInfo.OpenEulerSANum
		if branchCount <= 1 {
			introduction = v.Introduction
			topic = v.Theme
		} else if branchCount == 2 {
			introduction = strings.ReplaceAll(v.Introduction, affectBranch, strings.Join(branchList, " and "))
			topic = strings.ReplaceAll(v.Theme, affectBranch, strings.Join(branchList, " and "))
		} else {
			reBanch := strings.Join(branchList[:len(branchList)-1], ",") + " and " + branchList[len(branchList)-1]
			introduction = strings.ReplaceAll(v.Introduction, affectBranch, reBanch)
			topic = strings.ReplaceAll(v.Theme, affectBranch, reBanch)
		}
	} else {
		introduction = v.Introduction
		topic = v.Theme
		localOpenEulerSANum = componentInfo.CveNumMap[affectBranch].OpenEulerSANum
	}
	if len(introduction) > 1 {
		documt.DocumentTitle = introduction[:len(introduction)-1]
	} else {
		documt.DocumentTitle = introduction
	}
	documt.XmlLang = "en"
	cvrfsa.DocumentTitle = &documt
	cvrfsa.DocumentType = "Security Advisory"
	var documentPublisher DocumentPublisher
	documentPublisher.Type = "Vendor"
	documentPublisher.ContactDetails = "openeuler-security@openeuler.org"
	documentPublisher.IssuingAuthority = "openEuler security committee"
	cvrfsa.DocumentPublisher = &documentPublisher
	var documentTracking DocumentTracking
	var identification Identification
	identification.Id = localOpenEulerSANum
	documentTracking.Identification = &identification
	documentTracking.Status = "Final"
	documentTracking.Version = "1.0"
	var revisionHistory RevisionHistory
	revision := make([]Revision, 0)
	if cvrfsa.DocumentTracking != nil &&
		cvrfsa.DocumentTracking.RevisionHistory != nil &&
		len(cvrfsa.DocumentTracking.RevisionHistory.Revision) > 0 &&
		componentInfo.UpdateFlag == 1 {
		RevisionSlice := cvrfsa.DocumentTracking.RevisionHistory.Revision
		for _, rev := range RevisionSlice {
			revision = append(revision, rev)
		}
		versionValue := float64(len(RevisionSlice))/float64(10) + float64(1)
		var revisionx Revision
		revisionx.Number = fmt.Sprintf("%.1f", versionValue)
		revisionx.Date = v.PublicDate
		revisionx.Description = "Update"
		revision = append(revision, revisionx)
		documentTracking.Version = revisionx.Number
	} else {
		var revisionx Revision
		revisionx.Number = "1.0"
		revisionx.Date = v.PublicDate
		revisionx.Description = "Initial"
		revision = append(revision, revisionx)
		documentTracking.InitialReleaseDate = v.PublicDate
	}
	revisionHistory.Revision = revision
	documentTracking.RevisionHistory = &revisionHistory
	documentTracking.CurrentReleaseDate = v.PublicDate
	var generator Generator
	generator.Date = curDate
	generator.Engine = "openEuler SA Tool V1.0"
	documentTracking.Generator = &generator
	cvrfsa.DocumentTracking = &documentTracking
	BuilddocumentNotes(cvrfsa, v, introduction, topic,
		affectBranch, componentMap, branchList, branchFlag)
}

func BuildDocumentRef(cvrfsa *CvrfSa, v models.ExcelExport,
	componentMap map[string]ComponentInfo, branchFlag int, affectBranch string) {
	componentInfo, comOk := componentMap[v.InfluenceComponent]
	localOpenEulerSANum := ""
	secLinkConfig := beego.AppConfig.String("reflink::openeuler_web")
	localCveNum := []string{}
	if branchFlag == 1 {
		localOpenEulerSANum = componentInfo.OpenEulerSANum
		localCveNum = componentInfo.CveNum
	} else {
		localOpenEulerSANum = componentInfo.CveNumMap[affectBranch].OpenEulerSANum
		localCveNum = componentInfo.CveNumMap[affectBranch].CveNumSlice
	}
	if comOk {
		if cvrfsa.DocumentReferences != nil && len(cvrfsa.DocumentReferences.CveReference) > 0 {
			cveReference := cvrfsa.DocumentReferences.CveReference
			cveReferencex := make([]CveReference, 0)
			for _, cveRef := range cveReference {
				if cveRef.Type == "openEuler CVE" {
					isExist := false
					for _, cUrl := range cveRef.CveUrl {
						if strings.Contains(cUrl.Url, v.CveNum) {
							isExist = true
						}
					}
					if !isExist {
						var cveUrl1 CveUrl
						cveUrl1.Url = secLinkConfig + "/en/security/cve/detail.html?id=" + v.CveNum
						cveRef.CveUrl = append(cveRef.CveUrl, cveUrl1)
					}
				}
				if cveRef.Type == "Other" {
					isExist := false
					for _, cUrl := range cveRef.CveUrl {
						if strings.Contains(cUrl.Url, v.CveNum) {
							isExist = true
						}
					}
					if !isExist {
						var cveUrl2 CveUrl
						cveUrl2.Url = "https://nvd.nist.gov/vuln/detail/" + v.CveNum
						cveRef.CveUrl = append(cveRef.CveUrl, cveUrl2)
					}
				}
				cveReferencex = append(cveReferencex, cveRef)
			}
			cvrfsa.DocumentReferences.CveReference = cveReferencex
		} else {
			var documentReferences DocumentReferences
			cveReferenceSlice := make([]CveReference, 0)
			var cveReference0 CveReference
			cveUrlSlice0 := make([]CveUrl, 0)
			var cveUrl0 CveUrl
			cveUrl0.Url = secLinkConfig + "/en/security/safety-bulletin/detail.html?id=" + localOpenEulerSANum
			cveUrlSlice0 = append(cveUrlSlice0, cveUrl0)
			cveReference0.Type = "Self"
			cveReference0.CveUrl = cveUrlSlice0
			cveReferenceSlice = append(cveReferenceSlice, cveReference0)
			var cveReference1 CveReference
			cveUrlSlice1 := make([]CveUrl, 0)
			for _, cveNum := range localCveNum {
				var cveUrl1 CveUrl
				cveUrl1.Url = secLinkConfig + "/en/security/cve/detail.html?id=" + cveNum
				cveUrlSlice1 = append(cveUrlSlice1, cveUrl1)
			}
			cveReference1.Type = "openEuler CVE"
			cveReference1.CveUrl = cveUrlSlice1
			cveReferenceSlice = append(cveReferenceSlice, cveReference1)
			var cveReference2 CveReference
			cveUrlSlice2 := make([]CveUrl, 0)
			for _, cveNum := range localCveNum {
				var cveUrl2 CveUrl
				cveUrl2.Url = "https://nvd.nist.gov/vuln/detail/" + cveNum
				cveUrlSlice2 = append(cveUrlSlice2, cveUrl2)
			}
			cveReference2.Type = "Other"
			cveReference2.CveUrl = cveUrlSlice2
			cveReferenceSlice = append(cveReferenceSlice, cveReference2)
			documentReferences.CveReference = cveReferenceSlice
			cvrfsa.DocumentReferences = &documentReferences
		}
	}
}

func BuildProductTree(cvrfsa *CvrfSa, v models.ExcelExport, pkg []models.Package,
	affectBranch string, branchFlag int) {
	if cvrfsa.ProductTree != nil && len(cvrfsa.ProductTree.OpenEulerBranch) > 0 && branchFlag == 1 {
		affectBranchListx := strings.Split(affectBranch, "-")
		cpe := fmt.Sprintf("cpe:/a:%v:%v:%v",
			affectBranchListx[0], affectBranchListx[0], strings.Join(affectBranchListx[1:], "-"))
		openEulerBranchx := make([]OpenEulerBranch, 0)
		for _, opBranch := range cvrfsa.ProductTree.OpenEulerBranch {
			if opBranch.Type == "Product Name" && strings.Contains(affectBranch, opBranch.Name) {
				fpFlag := false
				for _, fp := range opBranch.FullProductName {
					if fp.FullProductName == affectBranch {
						fpFlag = true
						break
					}
				}
				if !fpFlag {
					var fullProductName0 FullProductName
					fullProductName0.FullProductName = affectBranch
					fullProductName0.ProductId = affectBranch
					fullProductName0.Cpe = cpe
					opBranch.FullProductName = append(opBranch.FullProductName, fullProductName0)
				}
			}
			if opBranch.Type == "Package Arch" {
				fullProductNameSliceaarch64 := make([]FullProductName, 0)
				fullProductNameSlicenoarch := make([]FullProductName, 0)
				fullProductNameSlicesrc := make([]FullProductName, 0)
				fullProductNameSlicex86_64 := make([]FullProductName, 0)
				if len(pkg) > 0 {
					for _, pk := range pkg {
						if opBranch.Name == "aarch64" {
							isExist := false
							for _, fp := range opBranch.FullProductName {
								if fp.FullProductName == pk.PackName && fp.Cpe == cpe {
									isExist = true
									break
								}
							}
							if !isExist && strings.Contains(pk.PackName, ".aarch64.") {
								var fullProductNameaarch64 FullProductName
								fullProductNameaarch64.FullProductName = pk.PackName
								fullProductNameaarch64.Cpe = cpe
								index := strings.LastIndex(pk.PackName, ".oe1.")
								if index > 0 {
									fullProductNameaarch64.ProductId = pk.PackName[:index]
								}
								fullProductNameSliceaarch64 = append(fullProductNameSliceaarch64, fullProductNameaarch64)
							}
						} else if opBranch.Name == "noarch" {
							isExist := false
							for _, fp := range opBranch.FullProductName {
								if fp.FullProductName == pk.PackName && fp.Cpe == cpe {
									isExist = true
									break
								}
							}
							if !isExist && strings.Contains(pk.PackName, ".noarch.") {
								var fullProductNamenoarch FullProductName
								fullProductNamenoarch.FullProductName = pk.PackName
								fullProductNamenoarch.Cpe = cpe
								index := strings.LastIndex(pk.PackName, ".oe1.")
								if index > 0 {
									fullProductNamenoarch.ProductId = pk.PackName[:index]
								}
								fullProductNameSlicenoarch = append(fullProductNameSlicenoarch, fullProductNamenoarch)
							}
						} else if opBranch.Name == "x86_64" {
							isExist := false
							for _, fp := range opBranch.FullProductName {
								if fp.FullProductName == pk.PackName && fp.Cpe == cpe {
									isExist = true
									break
								}
							}
							if !isExist && strings.Contains(pk.PackName, ".x86_64.") {
								var fullProductNamex86_64 FullProductName
								fullProductNamex86_64.FullProductName = pk.PackName
								fullProductNamex86_64.Cpe = cpe
								index := strings.LastIndex(pk.PackName, ".oe1.")
								if index > 0 {
									fullProductNamex86_64.ProductId = pk.PackName[:index]
								}
								fullProductNameSlicex86_64 = append(fullProductNameSlicex86_64, fullProductNamex86_64)
							}
						} else {
							isExist := false
							for _, fp := range opBranch.FullProductName {
								if fp.FullProductName == pk.PackName && fp.Cpe == cpe {
									isExist = true
									break
								}
							}
							if !isExist && strings.Contains(pk.PackName, ".src.") {
								var fullProductNamesrc FullProductName
								fullProductNamesrc.FullProductName = pk.PackName
								fullProductNamesrc.Cpe = cpe
								index := strings.LastIndex(pk.PackName, ".oe1.")
								if index > 0 {
									fullProductNamesrc.ProductId = pk.PackName[:index]
								}
								fullProductNameSlicesrc = append(fullProductNameSlicesrc, fullProductNamesrc)
							}
						}
					}
				}
				if opBranch.Name == "aarch64" {
					opBranch.FullProductName = append(opBranch.FullProductName, fullProductNameSliceaarch64...)
				} else if opBranch.Name == "noarch" {
					opBranch.FullProductName = append(opBranch.FullProductName, fullProductNameSlicenoarch...)
				} else if opBranch.Name == "x86_64" {
					opBranch.FullProductName = append(opBranch.FullProductName, fullProductNameSlicex86_64...)
				} else {
					opBranch.FullProductName = append(opBranch.FullProductName, fullProductNameSlicesrc...)
				}
			}
			openEulerBranchx = append(openEulerBranchx, opBranch)
		}
		cvrfsa.ProductTree.OpenEulerBranch = openEulerBranchx
	} else {
		var productTree ProductTree
		productTree.Xmlns = "http://www.icasi.org/CVRF/schema/prod/1.1"
		openEulerBranchSlice := make([]OpenEulerBranch, 0)
		var openEulerBranch0 OpenEulerBranch
		fullProductNameSlice0 := make([]FullProductName, 0)
		var fullProductName0 FullProductName
		fullProductName0.FullProductName = affectBranch
		fullProductName0.ProductId = affectBranch
		affectBranchListx := strings.Split(affectBranch, "-")
		cpe := fmt.Sprintf("cpe:/a:%v:%v:%v",
			affectBranchListx[0], affectBranchListx[0], strings.Join(affectBranchListx[1:], "-"))
		fullProductName0.Cpe = cpe
		fullProductNameSlice0 = append(fullProductNameSlice0, fullProductName0)
		openEulerBranch0.FullProductName = fullProductNameSlice0
		openEulerBranch0.Type = "Product Name"
		openEulerBranch0.Name = affectBranchListx[0]
		openEulerBranchSlice = append(openEulerBranchSlice, openEulerBranch0)
		fullProductNameSliceaarch64 := make([]FullProductName, 0)
		fullProductNameSlicenoarch := make([]FullProductName, 0)
		fullProductNameSlicesrc := make([]FullProductName, 0)
		fullProductNameSlicex86_64 := make([]FullProductName, 0)
		if len(pkg) > 0 {
			for _, pk := range pkg {
				if strings.Contains(pk.PackName, ".aarch64.") {
					var fullProductNameaarch64 FullProductName
					fullProductNameaarch64.FullProductName = pk.PackName
					fullProductNameaarch64.Cpe = cpe
					index := strings.LastIndex(pk.PackName, ".oe1.")
					if index > 0 {
						fullProductNameaarch64.ProductId = pk.PackName[:index]
					}
					fullProductNameSliceaarch64 = append(fullProductNameSliceaarch64, fullProductNameaarch64)
				} else if strings.Contains(pk.PackName, ".src.") {
					var fullProductNamesrc FullProductName
					fullProductNamesrc.FullProductName = pk.PackName
					fullProductNamesrc.Cpe = cpe
					index := strings.LastIndex(pk.PackName, ".oe1.")
					if index > 0 {
						fullProductNamesrc.ProductId = pk.PackName[:index]
					}
					fullProductNameSlicesrc = append(fullProductNameSlicesrc, fullProductNamesrc)
				} else if strings.Contains(pk.PackName, ".x86_64.") {
					var fullProductNamex86_64 FullProductName
					fullProductNamex86_64.FullProductName = pk.PackName
					fullProductNamex86_64.Cpe = cpe
					index := strings.LastIndex(pk.PackName, ".oe1.")
					if index > 0 {
						fullProductNamex86_64.ProductId = pk.PackName[:index]
					}
					fullProductNameSlicex86_64 = append(fullProductNameSlicex86_64, fullProductNamex86_64)
				} else {
					var fullProductNamenoarch FullProductName
					fullProductNamenoarch.FullProductName = pk.PackName
					fullProductNamenoarch.Cpe = cpe
					index := strings.LastIndex(pk.PackName, ".oe1.")
					if index > 0 {
						fullProductNamenoarch.ProductId = pk.PackName[:index]
					}
					fullProductNameSlicenoarch = append(fullProductNameSlicenoarch, fullProductNamenoarch)
				}
			}
		}
		if len(fullProductNameSliceaarch64) > 0 {
			var openEulerBranchaarch64 OpenEulerBranch
			openEulerBranchaarch64.Type = "Package Arch"
			openEulerBranchaarch64.Name = "aarch64"
			openEulerBranchaarch64.FullProductName = fullProductNameSliceaarch64
			openEulerBranchSlice = append(openEulerBranchSlice, openEulerBranchaarch64)
		}
		if len(fullProductNameSlicenoarch) > 0 {
			var openEulerBranchnoarch OpenEulerBranch
			openEulerBranchnoarch.Type = "Package Arch"
			openEulerBranchnoarch.Name = "noarch"
			openEulerBranchnoarch.FullProductName = fullProductNameSlicenoarch
			openEulerBranchSlice = append(openEulerBranchSlice, openEulerBranchnoarch)
		}
		if len(fullProductNameSlicesrc) > 0 {
			var openEulerBranchsrc OpenEulerBranch
			openEulerBranchsrc.Type = "Package Arch"
			openEulerBranchsrc.Name = "src"
			openEulerBranchsrc.FullProductName = fullProductNameSlicesrc
			openEulerBranchSlice = append(openEulerBranchSlice, openEulerBranchsrc)
		}
		if len(fullProductNameSlicex86_64) > 0 {
			var openEulerBranchx86_64 OpenEulerBranch
			openEulerBranchx86_64.Type = "Package Arch"
			openEulerBranchx86_64.Name = "x86_64"
			openEulerBranchx86_64.FullProductName = fullProductNameSlicex86_64
			openEulerBranchSlice = append(openEulerBranchSlice, openEulerBranchx86_64)
		}
		productTree.OpenEulerBranch = openEulerBranchSlice
		cvrfsa.ProductTree = &productTree
	}
}

func BuildVulnerability(vlLenth int, v models.ExcelExport,
	componentMap map[string]ComponentInfo, cpe string, branchFlag int) []Vulnerability {
	vulnerabilitySlice := make([]Vulnerability, 0)
	var vulnerability Vulnerability
	vulnerability.Xmlns = "http://www.icasi.org/CVRF/schema/vuln/1.1"
	vulnerability.Ordinal = strconv.Itoa(vlLenth)
	var cveNotes CveNotes
	var cveNote CveNote
	cveNote.Ordinal = strconv.Itoa(vlLenth)
	cveNote.Type = "General"
	cveNote.Title = "Vulnerability Description"
	cveBrief := XmlSpecCharHand(v.CveBrief)
	cveNote.Note = cveBrief
	cveNote.XmlLnag = "en"
	cveNotes.CveNote = &cveNote
	vulnerability.CveNotes = &cveNotes
	vulnerability.ReleaseDate = v.PublicDate
	vulnerability.Cve = v.CveNum
	var productStatuses ProductStatuses
	var status Status
	status.Type = "Fixed"
	var productId ProductId
	productId.ProductId = cpe
	productIdSlice := make([]ProductId, 0)
	productIdSlice = append(productIdSlice, productId)
	status.ProductId = productIdSlice
	productStatuses.Status = &status
	vulnerability.ProductStatuses = &productStatuses
	var threats Threats
	var threat Threat
	threat.Type = "Impact"
	threat.Description = models.OpenEulerScoreProc(v.OpenEulerScore)
	threats.Threat = &threat
	vulnerability.Threats = &threats
	var cVSSScoreSets CVSSScoreSets
	var scoreSet ScoreSet
	scoreSet.BaseScore = fmt.Sprintf("%.1f", v.OpenEulerScore)
	scoreSet.Vector = v.OvectorVule
	cVSSScoreSets.ScoreSet = &scoreSet
	vulnerability.CvssScoreSets = &cVSSScoreSets
	var remediations Remediations
	var remediation Remediation
	remediation.Type = "Vendor Fix"
	remediation.Description = v.Summary
	remediation.Date = v.PublicDate
	ownedComponent := ""
	if len(v.InfluenceComponent) > 1 {
		ownedComponent = v.InfluenceComponent
	} else {
		ownedComponent = v.OwnedComponent
	}
	componentInfo := componentMap[ownedComponent]
	localOpenEulerSANum := ""
	if branchFlag == 1 {
		localOpenEulerSANum = componentInfo.OpenEulerSANum
	} else {
		localOpenEulerSANum = componentInfo.CveNumMap[cpe].OpenEulerSANum
	}
	secLinkConfig := beego.AppConfig.String("reflink::openeuler_web")
	remediation.Url = secLinkConfig + "/en/security/safety-bulletin/detail.html?id=" + localOpenEulerSANum
	remediations.Remediation = &remediation
	vulnerability.Remediations = &remediations
	vulnerabilitySlice = append(vulnerabilitySlice, vulnerability)
	return vulnerabilitySlice
}

func BuildVulnerabilitySlice(vulnerability []Vulnerability, v models.ExcelExport,
	affectBranch string, componentMap map[string]ComponentInfo, branchFlag int) []Vulnerability {
	//affectBranchListx := strings.Split(affectBranch, "-")
	cpe := affectBranch
	if vulnerability != nil && len(vulnerability) > 0 {
		cveExist := false
		for _, vl := range vulnerability {
			if vl.Cve == v.CveNum && strings.Contains(vl.Remediations.Remediation.Description, v.InfluenceComponent) {
				cpeExist := false
				for _, pid := range vl.ProductStatuses.Status.ProductId {
					if pid.ProductId == cpe {
						cpeExist = true
						break
					}
				}
				if !cpeExist {
					var productId ProductId
					productId.ProductId = cpe
					if branchFlag == 1 {
						vl.ProductStatuses.Status.ProductId = append(vl.ProductStatuses.Status.ProductId, productId)
					} else {
						productIdSlice := make([]ProductId, 0)
						productIdSlice = append(productIdSlice, productId)
						vl.ProductStatuses.Status.ProductId = productIdSlice
					}
				}
				cveExist = true
				break
			}
		}
		if !cveExist {
			vlLenth := len(vulnerability) + 1
			vulnerabilitySlice := BuildVulnerability(vlLenth, v, componentMap, cpe, branchFlag)
			if len(vulnerabilitySlice) > 0 {
				vulnerability = append(vulnerability, vulnerabilitySlice...)
			}
		}
	} else {
		vlLenth := 1
		vulnerabilitySlice := BuildVulnerability(vlLenth, v, componentMap, cpe, branchFlag)
		vulnerability = append(vulnerability, vulnerabilitySlice...)
	}
	return vulnerability
}

func BuildVulnerabilitySet(cvrfsa *CvrfSa, v models.ExcelExport,
	affectBranch string, componentMap map[string]ComponentInfo, branchFlag int) {
	vulnerability := make([]Vulnerability, 0)
	if cvrfsa.Vulnerability != nil && len(cvrfsa.Vulnerability) > 0 {
		for _, vuln := range cvrfsa.Vulnerability {
			vulnerability = append(vulnerability, vuln)
		}
	}
	vulnerabilityx := BuildVulnerabilitySlice(vulnerability, v,
		affectBranch, componentMap, branchFlag)
	cvrfsa.Vulnerability = vulnerabilityx
}

func BuildCvrfXml(cvrfsa *CvrfSa, v models.ExcelExport, affectBranch string,
	cvrfFileList map[string][]string, componentMap map[string]ComponentInfo,
	pkg []models.Package, branchFlag int) {
	curDate := common.GetCurDate()
	branchList := BranchExist(affectBranch, cvrfFileList)
	cvrfsa.Xmlns = "http://www.icasi.org/CVRF/schema/cvrf/1.1"
	cvrfsa.XmlnsCvrf = "http://www.icasi.org/CVRF/schema/cvrf/1.1"
	BuildDocumentTitle(cvrfsa, v, affectBranch, cvrfFileList, componentMap, curDate, branchList, branchFlag)
	BuildDocumentRef(cvrfsa, v, componentMap, branchFlag, affectBranch)
	BuildProductTree(cvrfsa, v, pkg, affectBranch, branchFlag)
	BuildVulnerabilitySet(cvrfsa, v, affectBranch, componentMap, branchFlag)
}

func QueryCveMd5(cveNum []string, OwnedComponent, openEulerSANum string, fixFlag int8) (bool, string) {
	sort.Strings(cveNum)
	tmpOpenEulerSANum := ""
	cveStr := strings.Join(cveNum, ",")
	cveStrx := cveStr + "," + OwnedComponent
	fileMd5 := common.EncryptMd5(cveStrx)
	var cfr models.CvrfSaRecord
	cfr.Md5 = fileMd5
	tbErr := models.GetCvrfRecord(&cfr, "cur_md5")
	if tbErr == nil {
		tmpOpenEulerSANum = cfr.OpenEulerSANum
		cfr.UpdateTime = common.GetCurTime()
		cfr.Md5 = fileMd5
		cfr.OpenEulerSANum = openEulerSANum
		cfr.Status = 1
		cfr.IsExport = 1
		cfr.CveNum = cveStr
		cfr.PackName = OwnedComponent
		cfr.AffectFlag = fixFlag
		updateErr := models.UpdateCvrfRecord(&cfr, "UpdateTime",
			"OpenEulerSANum", "Status", "IsExport", "CveNum", "PackName", "AffectFlag")
		if updateErr != nil {
			logs.Error("UpdateCvrfRecord, ", updateErr)
		}
		return true, tmpOpenEulerSANum
	} else {
		cfr.CreateTime = common.GetCurTime()
		cfr.Md5 = fileMd5
		cfr.OpenEulerSANum = openEulerSANum
		cfr.Status = 1
		cfr.IsExport = 1
		cfr.CveNum = cveStr
		cfr.PackName = OwnedComponent
		cfr.AffectFlag = fixFlag
		num, iErr := models.InsertCvrfRecord(&cfr)
		if iErr != nil || num == 0 {
			logs.Error("InsertCvrfRecord, ", iErr)
		}
		return false, tmpOpenEulerSANum
	}
}

func UpdateCvrfRecord(openeuler_sa_num string, isExport int8) {
	var cfr models.CvrfSaRecord
	cfr.UpdateTime = common.GetCurTime()
	cfr.Status = 1
	cfr.IsExport = isExport
	cfr.OpenEulerSANum = openeuler_sa_num
	uErr := models.UpdateCvrfRecord(&cfr, "UpdateTime", "Status", "IsExport")
	if uErr != nil {
		logs.Error("UpdateCvrfRecord, ", uErr)
	}
}

func ProcCvrfFileName(fileName string) {
	var cfr models.SaFileList
	cfr.FileName = fileName
	tbErr := models.GetCvrfFileName(&cfr, "file_name")
	if tbErr == nil {
		cfr.Status = 1
		cfr.UpdateTime = common.GetCurTime()
		models.UpdateCvrfFileName(&cfr, "Status", "UpdateTime")
	} else {
		cfr.CreateTime = common.GetCurTime()
		cfr.Status = 1
		cfr.FileName = fileName
		num, iErr := models.InsertCvrfFileName(&cfr)
		if iErr != nil || num == 0 {
			logs.Error("InsertCvrfRecord, ", iErr)
		}
	}
}

func RecordCrvfInfo(fileName, filex, newText string, fixFlag int8) error {
	fileBytes, err := ioutil.ReadFile(fileName)
	if err != nil {
		fmt.Println("ioutil.ReadFile, error : %s", err, fileName)
		return err
	}
	fileStr := string(fileBytes)
	fileMd5 := common.EncryptMd5(fileStr)
	openEulerSANum := ""
	if fixFlag == UNAFFECTFLAG {
		openEulerSANum = fileMd5
	} else {
		if len(filex) > 5 {
			openEulerSANum = filex[5 : len(filex)-4]
		}
	}
	fileContent := fileBytes
	var buf bytes.Buffer
	compressor, err := zlib.NewWriterLevelDict(&buf, zlib.BestCompression, fileBytes)
	if err != nil {
		fmt.Println("Compression failed")
	} else {
		compressor.Write(fileBytes)
		compressor.Close()
		fileContent = buf.Bytes()
	}
	fileConStr := baseStdEncode(fileContent)
	var cfr models.CvrfSaRecord
	cfr.OpenEulerSANum = openEulerSANum
	if fixFlag == UNAFFECTFLAG {
		cfr.Md5 = fileMd5
	}
	//cfr.Md5 = fileMd5
	tbErr := models.GetCvrfRecord(&cfr, "openeuler_sa_num")
	if tbErr != nil || cfr.Id == 0 {
		cfr.CreateTime = common.GetCurTime()
		if fixFlag == UNAFFECTFLAG {
			cfr.Md5 = fileMd5
			cfr.CveNum = " "
			cfr.PackName = " "
		}
		cfr.OpenEulerSANum = openEulerSANum
		cfr.XmlContent = fileConStr
		cfr.Status = 1
		cfr.IsExport = 1
		cfr.AffectFlag = fixFlag
		cfr.SortOpenEulerSANum = newText
		num, iErr := models.InsertCvrfRecord(&cfr)
		if iErr != nil || num == 0 {
			logs.Error("InsertCvrfRecord, ", iErr)
		}
	} else {
		cfr.UpdateTime = common.GetCurTime()
		if fixFlag == UNAFFECTFLAG {
			cfr.Md5 = fileMd5
		}
		cfr.XmlContent = fileConStr
		cfr.Status = 1
		cfr.IsExport = 1
		cfr.AffectFlag = fixFlag
		cfr.SortOpenEulerSANum = newText
		uErr := models.UpdateCvrfRecord(&cfr, "UpdateTime", "UpdateMd5", "XmlContent",
			"Status", "IsExport", "AffectFlag", "SortOpenEulerSANum")
		if uErr != nil {
			logs.Error("UpdateCvrfRecord, ", uErr)
		}
	}
	return nil
}

// File Upload
func PostFile(filename string, targetUrl string) error {
	upfileErr := ObsUploadFile(targetUrl, filename)
	if upfileErr != nil {
		logs.Error("upfileErr: ", upfileErr)
	}
	return upfileErr
}

//downlaod file
func GetFile(url, filePath string) error {
	res, err := http.Get(url)
	if err != nil {
		logs.Error("GetFile1, err: ", err)
		return err
	}
	f, err := os.Create(filePath)
	if err != nil {
		logs.Error("GetFile2, err: ", err)
		return err
	}
	io.Copy(f, res.Body)
	return nil
}

func ReadWriteFile(filePath string, fileSlice []string) error {
	if len(fileSlice) == 0 {
		return errors.New("file content does not exist")
	}
	localDataSlice := make([]string, 0)
	localDataSlice = common.RemoveDupString(fileSlice)
	sort.Strings(localDataSlice)
	fileContent := strings.Join(localDataSlice, "\n")
	fisExist, _ := PathExists(filePath)
	if fisExist {
		os.Remove(filePath)
	}
	file, err := os.Create(filePath)
	if err != nil {
		logs.Error("open file err", err)
		return err
	}
	defer file.Close()
	_, err = file.Write([]byte(fileContent))
	if err != nil {
		logs.Error(err)
	}
	return nil
}

func ReadFileAll(filePath string) string {
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	defer file.Close()
	fileinfo, err := file.Stat()
	if err != nil {
		fmt.Println(err)
		return ""
	}
	filesize := fileinfo.Size()
	buffer := make([]byte, filesize)

	bytesread, err := file.Read(buffer)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	logs.Info("bytes read: ", bytesread)
	logs.Info("bytestream to string: ", string(buffer))
	return string(buffer)
}

type ReplaceHelper struct {
	OldPath string
	NewPath string
	OldText string
	NewText string
}

func (h *ReplaceHelper) DoWrok() error {
	return filepath.Walk(h.OldPath, h.walkCallback)
}

func (h ReplaceHelper) walkCallback(path string, f os.FileInfo, err error) error {
	if err != nil {
		return err
	}
	if f == nil {
		return nil
	}
	if f.IsDir() {
		return nil
	}
	buf, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}
	content := string(buf)
	newContent := strings.Replace(content, h.OldText, h.NewText, -1)
	ioutil.WriteFile(h.NewPath, []byte(newContent), 0)
	return err
}
